package insect.leg;

import java.awt.Graphics2D;
import math.vectorSpace.R3.Point3D;
import math.vectorSpace.R3.Segment3D;
import math.vectorSpace.R3.Vector3D;
import math.vectorSpace.R3.object.MovableObject;
import math.vectorSpace.R3.visualization.Render3D;
import math.vectorSpace.R3.visualization.VisualizationProperties;

public class InsectLeg extends MovableObject{

    private Point3D attachPoint;

    /* 
    segments[0] = lateral reference vector
    segments[1] = vertical reference vector
    
    segments[2] = lateral component of attached segment
    segments[3] = vertical component of attached segment
    
    segments[4] = attached segment
    
    iterate starting from index 5
     */
    private Vector3D[] segments;

    /*	 	
    minAngles[0] = lateral angle
    minAngles[1] = vertical angle
    
    iterate starting from index 2
     */
    private Integer[] minAngles, maxAngles;

    /*	 
    deltaAngles[0] = lateral delta angle
    deltaAngles[1] = vertical delta angle
    
    iterate starting from index 2
     */
    private Double[] deltaAngles;

    public InsectLeg(Point3D attachPoint, Vector3D[] segments,
            Integer[] minAngles, Integer[] maxAngles, Double[] deltaAngles) {
        this.attachPoint = attachPoint;
        this.segments = segments;
        this.minAngles = minAngles;
        this.maxAngles = maxAngles;
        this.deltaAngles = deltaAngles;

    }

    private Vector3D rotateSegment(Vector3D segment, Vector3D referenceSegment,
            int i) {
        double angle = segment.angleD(referenceSegment);

        if ((angle - 1 <= minAngles[i]) || (angle + 1 >= maxAngles[i])) {
            deltaAngles[i] = -deltaAngles[i];
        }
        return segment.rotateTowards(referenceSegment, deltaAngles[i]);
    }

    @Override
    public void move() {
        // Rotate the attached segment
        segments[2] = rotateSegment(segments[2], segments[0], 0);
        segments[3] = rotateSegment(segments[3], segments[1], 1);
        segments[4] = segments[2].add(segments[3]);

        // Rotate the rest of the segments
        for (int i = 4; i < segments.length - 1; i++) {
            segments[i + 1] = rotateSegment(segments[i + 1], segments[i], i - 2);
        }
    }

    private Segment3D[] getDraw() {
        Point3D p1, p2;
        p2 = new Point3D(attachPoint);
        Segment3D[] segmentList = new Segment3D[segments.length - 4];

        for (int i = 0; i < segments.length - 4; i++) {
            p1 = p2;
            p2 = p1.add(segments[i + 4]);
            segmentList[i] = new Segment3D(p1, p2);
        }

        return segmentList;
    }

    @Override
    public void draw(Render3D render, Graphics2D graphics, 
            VisualizationProperties properties) {
        Segment3D[] segmentList = getDraw();

        for (Segment3D s : segmentList) {
            s.draw(render, graphics, properties);
        }
    }
}